#pragma once
#include <vector>

// a class is used for storing a secret in sharing secret scheme
template<typename T>
class ss_secret
{
public:
    ss_secret(const T& value): 
        _value(value){}

    T get_secret() const
    {
        return _value;
    }
protected:
    T _value;
};

// a class is used for storing share of a secret in sharing secret scheme
template<typename T>
class ss_share
{
public:
    ss_share(const T& value): 
        _value(value)
		{

		}

    T get_share() const
    {
        return _value;
    }
protected:
    T _value;
};

#include <fstream>
#include <string>
// a class represents a player in sharing secret scheme
template<typename shareT>
class ss_player
{
public:
    ss_player(): _share(NULL) {}
    ~ss_player(){ if(_share!=NULL) delete _share; }
    virtual shareT get_share() const
    {
        return _share->get_share();
    }
    virtual void set_share(const ss_share<shareT> *const share, int i)
    {
        this->_share = new ss_share<shareT>(*share);
		char buf[3];

		_itoa_s(i, buf,10);
		std::string path = ".\\shares\\";
		path.append(buf);
		std::ofstream outfile(path);
		outfile<<(_share->get_share());

		outfile.close();
	}
	ss_player(const ss_player<shareT>& value)
	{
		this->_share = new ss_share<shareT>(value._share);
	}
protected:
    ss_share<shareT>* _share;
};

template<typename shareT>
class ss_players: public std::vector<ss_player<shareT>* const> {};

// a class represents a dealer in sharing secret scheme
template<typename shareT, typename secretT>
class ss_dealer: public ss_player<shareT>
{
public:
    virtual void distribute_secret(
        const ss_secret<secretT> *const secret,
        const ss_players<shareT>& players) const = 0;

     virtual ss_secret<secretT> *const restore_secret(
         const ss_players<shareT>& players) const = 0;
};